(function() {
    Nokia.Carousel = Nokia.Widget.extend({
        initialize: function(options) {
            var instance = this;

			var defaults = {
				items: '> li',
				backgroundClass: 'ui-state-default',
				visibleItems: 5,
				applyTransition: false,
				delay: 1000,
				itemDimensions: {
					height: 75,
					width: 75
				},
				select: function(event, item) {}
            };

            instance.options = jQuery.extend(defaults, options);

            instance._super.apply(instance, [instance.options]);

            instance.registerData("carousel");

            var element = jQuery(options.element);

            instance.element = element;

            instance._create();

            instance._attachEvents();

			instance.registerVibrationOn([ 'create', 'scroll' ]);
			instance.fireCallback('create');
        },

		_attachEvents: function() {
			var instance = this;
			var element = instance.element;
			var Styles = instance.Styles;
			var leftArrow = instance.leftArrow;
			var rightArrow = instance.rightArrow;

			instance.arrows.hover(function() {
				jQuery(this).addClass(Styles.arrowFocused);
			}, function() {
				jQuery(this).removeClass(Styles.arrowFocused);
			});

			var prevAction = function(e) {
				instance.fireCallback('prev', e);
				instance.roll(-1);
			};

			var nextAction = function(e) {
				instance.fireCallback('next', e);
				instance.roll(1);
			};

			leftArrow.bind('click', prevAction);
			Nokia.util.bindEnter(leftArrow, prevAction);

			rightArrow.bind('click', nextAction);
			Nokia.util.bindEnter(rightArrow, nextAction);
		},

		_create: function() {
			var instance = this;
			var element = instance.element;
			var options = instance.options;
			var Styles = instance.Styles;
			var items = element.find(options.items);

			instance.items = items;

			Nokia.util.addClass(element[0], [Styles.clearFix, Styles.carouselClass].join(' '));

			var container = Nokia.dom.parseHTML('<div class="' + Styles.container +'"></div>');

			Nokia.dom.wrap(container, element);

			var wrapper = Nokia.dom.parseHTML('<div class="' + [Styles.wrapper, options.backgroundClass].join(' ') +'"></div>');

			Nokia.dom.wrap(wrapper, container);

			instance.wrapper = wrapper;
			instance.container = container;

			instance.selectedItem = items[(0)];

			items.each(function(i, item) {
				instance._createImageItem(jQuery(item));
			});

			instance._createArrows();

			instance._calculateDimensions();

			instance.roll(0, 0);
		},

		_createImageItem: function(item) {
			var instance = this,
				Styles = instance.Styles,
				options = instance.options;

			var wrapper = Nokia.dom.parseHTML('<a class="ui-helper-clearfix" href="javascript:void(0);"></a>');
			var img = item.find('img:first');

			Nokia.dom.wrap(wrapper, img);

			img[0].onload = function() {
				instance._resizeImage(img);

				instance._calculateDimensions();

				instance.roll(0, 0);
			};

			Nokia.util.addClass(item[0], Styles.itemClass);

			wrapper.hover(function() {
				wrapper.addClass(Styles.stateHover);
			}, function() {
				wrapper.removeClass(Styles.stateHover);
			});

			wrapper.click(function(event) {
				options.select.apply(instance, [event, item]);
			});

			Nokia.util.bindEnter(wrapper, function() {
				wrapper.trigger('click');
			});
		},

		_resizeImage: function(img) {

			var instance = this
				options = instance.options;

			img.css({
				width: options.itemDimensions.width,
				height: options.itemDimensions.height
			});
		},

		_calculateDimensions: function() {
			var instance = this;
			var tmpItem = instance.items.filter(':first');
			var tmpItemImg = tmpItem.find('img:first');

			var itemWidth = tmpItem.outerWidth() > 0 ? tmpItem.outerWidth() : instance.options.itemDimensions.width;

			// 2 pixel adjustment for hover borders
			var widths = (itemWidth + 2) * (instance.items.length);

			var elementWidth = widths;
			instance.element.width(elementWidth);
			instance.element.height(instance.options.itemDimensions.height);

			var wrapperWidth = (itemWidth) * instance.options.visibleItems;
			instance.wrapper.width(wrapperWidth);
			instance.container.width(wrapperWidth);

			var arrows = instance.arrows;

			arrows.css({
				height: instance.wrapper.outerHeight() - 4,
				width: instance.options.itemDimensions.width
			});
		},

		_createArrows: function() {
			var instance = this;
			var Styles = instance.Styles;
			var wrapper = instance.wrapper;

			instance.leftArrow = Nokia.dom.parseHTML('<a href="javascript:void(0);" class="'+ [Styles.arrow, Styles.leftArrow].join(' ') +'">&nbsp;</a>');
			instance.rightArrow = Nokia.dom.parseHTML('<a href="javascript:void(0);" class="'+ [Styles.arrow, Styles.rightArrow].join(' ') +'">&nbsp;</a>');

			Nokia.dom.append(wrapper, instance.leftArrow);
			Nokia.dom.append(wrapper, instance.rightArrow);

			instance.arrows = jQuery('.' + Styles.arrow, wrapper);
		},

		addItem: function(item) {
			var instance = this
				options = instance.options;

			instance._createImageItem(item);

			instance.selectedItem = instance.items[0];

			Nokia.dom.append(instance.element, item);

			instance.items = instance.element.find(options.items);;

			instance._calculateDimensions();
		},

		empty: function() {
			var instance = this;

			instance.items = [];

			instance.element.empty();
		},

		roll: function(increment, time) {
			var instance = this;
			var container = instance.container;
			var options = instance.options;
			var items = instance.items;
			var selectedItem = instance.selectedItem;
			var index = items.index(selectedItem);
			var nextSelected = items[(index + increment)];
			var delay = !isNaN(parseInt(time)) ? time : options.delay;
			var applyTransition = options.applyTransition;

			instance.arrows.show();

			if (nextSelected) {

				if (applyTransition) {
					delay = 0;
					Nokia.animation.prepareForTransition();
				}

				container.scrollTo(nextSelected, delay, function() {
					instance.selectedItem = nextSelected;

					if (applyTransition) {
						Nokia.animation.performTransition();
					}

					if (index + increment <= 0) {
						instance.leftArrow.hide();

						return;
					} else if (index + increment > (items.length - 1) - options.visibleItems) {
						instance.rightArrow.hide();

						return;
					}
				});

			}
		},

		Styles: {
			carouselClass: 'nokia-carousel-element',
			wrapper: 'nokia-carousel',
			container: 'nokia-carousel-container',
			arrow: 'nokia-carousel-arrow',
			leftArrow: 'nokia-carousel-arrow-left',
			rightArrow: 'nokia-carousel-arrow-right',
			arrowFocused: 'nokia-carousel-arrow-focused',
			itemClass: 'nokia-carousel-item',
			clearFix: 'ui-helper-clearfix',
			stateDefault: 'ui-state-default',
			stateHover: 'ui-state-hover'
		}

    });
})();
